/*
	Copyright (c) 2009, M.P. Bartnig & A. Gosman
	
	Permission is hereby granted, free of charge, to any person obtaining a copy
	of this software and associated documentation files (the "Software"), to deal
	in the Software without restriction, including without limitation the rights
	to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
	copies of the Software, and to permit persons to whom the Software is
	furnished to do so, subject to the following conditions:
	
	The above copyright notice and this permission notice shall be included in
	all copies or substantial portions of the Software.
	
	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
	IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
	FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
	AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
	LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
	OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
	THE SOFTWARE.
*/
package nl.sanity.net
{
	/**
	 * LoadItem
	 * 
	 * @langversion ActionScript 3
	 *
	 * @author A. Gosman
	 * @since  04/08/2009
	 */
	 
	import flash.display.Bitmap;
	import flash.display.DisplayObject;
	import flash.display.Loader;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.IOErrorEvent;
	import flash.events.ProgressEvent;
	import flash.events.SecurityErrorEvent;
	import flash.media.Sound;
	import flash.net.URLLoader;
	import flash.net.URLRequest;
	import flash.text.StyleSheet;
	
	import nl.sanity.events.QueueLoaderEvent;
	import nl.sanity.net.helpers.ContentType;
	

	public class LoadItem extends EventDispatcher
	{
		protected var _url			: String;
		protected var _id 			: String;
		protected var _useCache		: Boolean;
		
		protected var _contentType	: String;
		protected var _loader		: *;
		protected var _content		: *;
		
		
		public function LoadItem( url:String, id:String = null, useCache:Boolean = true )
		{
			_url 		= url;
			_id 		= id || _url;
			_useCache	= useCache;
		}
		
		
		// --- GETTERS / SETTERS ----------------------------------------------
		
		public function get url():String
		{
			return _url;
		}
		
		public function get id():String
		{
			return _id;
		}
		
		public function get contentType():String
		{
			return _contentType;
		}
		
		public function get content():*
		{
			return _content;
		}
		
		public function get loader():*
		{
			return _loader;
		}
		
		
		// --- PUBLIC METHODS -------------------------------------------------
		
		public function load():void
		{
			// Determine the load method based on the filename
			if ( _url.match( ".mp3" ) )
			{
				_loader = new Sound();
				_loader.addEventListener( ProgressEvent.PROGRESS, onLoadProgress );
				_loader.addEventListener( Event.COMPLETE, onLoadComplete );
				_loader.addEventListener( IOErrorEvent.IO_ERROR, onLoadError );
				_loader.addEventListener( SecurityErrorEvent.SECURITY_ERROR, onSecurityError );
			}
			else if ( 	_url.match( ".css" ) ||
						_url.match( ".xml" ) ||
						_url.match( ".txt" ) )
			{
				_loader = new URLLoader();
				_loader.addEventListener( ProgressEvent.PROGRESS, onLoadProgress );
				_loader.addEventListener( Event.COMPLETE, onLoadComplete );
				_loader.addEventListener( IOErrorEvent.IO_ERROR, onLoadError );
				_loader.addEventListener( SecurityErrorEvent.SECURITY_ERROR, onSecurityError );
			}
			else if (	_url.match( ".gif" ) ||
						_url.match( ".jpg" ) ||
						_url.match( ".png" ) ||
						_url.match( ".swf" ) )
			{
				_loader	= new Loader();
				_loader.contentLoaderInfo.addEventListener( ProgressEvent.PROGRESS, onLoadProgress );
				_loader.contentLoaderInfo.addEventListener( Event.COMPLETE, onLoadComplete );
				_loader.contentLoaderInfo.addEventListener( IOErrorEvent.IO_ERROR, onLoadError );
				_loader.contentLoaderInfo.addEventListener( SecurityErrorEvent.SECURITY_ERROR, onSecurityError );
			}
			else
			{
				// Not a known filetype
				throw new Error( "Could not load file. Reason: unsupported filetype" );
			}
			
			
			_loader.load( new URLRequest( _url ) );
		}
		
		public function close():void
		{
			_loader.close();
		}
		
		
		// --- PROTECTED METHODS -------------------------------------------------
		
		protected function getContentType():String
		{
			if ( _loader is Loader )
			{
				return _loader.contentLoaderInfo.contentType;
			}
			
			if ( _loader is URLLoader )
			{
				return _loader.dataFormat.toString();
			}
			
			if ( _loader is Sound )
			{
				return ContentType.MP3;
			}
			
			return null;
		}
		
		// --- EVENT HANDLERS -------------------------------------------------
		
		protected function onLoadProgress( event:ProgressEvent ):void
		{
			dispatchEvent( new QueueLoaderEvent( QueueLoaderEvent.ON_ITEM_LOAD_PROGRESS, { bytesLoaded: event.bytesLoaded, bytesTotal: event.bytesTotal } ) );
		}
		
		protected function onLoadComplete( event:Event ):void
		{
			// Determine contenttype
			_contentType		= getContentType();
			
			// Store the loaded source in the list
			switch ( _contentType )
			{
				case ContentType.GIF:
				case ContentType.JPG:
				case ContentType.PNG:
					_content		= _loader.content as Bitmap;
					break;
				
				case ContentType.SWF:
					// Since it depends how the baseclass of the loaded swf is extended, we use DisplayObject: this covers us all types of display extends.
					// Perhaps needs a workaround to check whether the clip is a MovieClip (thus has a timeline) or is a Sprite
					// In that case the getMovieClip function needs a rewrite too.
					_content		= _loader.content as DisplayObject;
					break;
					
				case ContentType.MP3:
					_content		= _loader as Sound;
					break;
					
				case ContentType.TXT:
					if ( _url.match( ".xml" ) )
					{
						// XML file
						_content	= XML( _loader.data );
					}
					else if ( _url.match( ".css" ) )
					{
						// CSS file
						var styleSheet:StyleSheet	= new StyleSheet();
						styleSheet.parseCSS( _loader.data );
						_content					= styleSheet;
					}
					else
					{
						// Plain text file
						_content					= _loader.data;
					}
					break;
			}
			
			// Notification
			dispatchEvent( new QueueLoaderEvent( QueueLoaderEvent.ON_ITEM_LOAD_COMPLETE ) );
		}
		
		protected function onLoadError( event:IOErrorEvent ):void
		{
			dispatchEvent( new QueueLoaderEvent( QueueLoaderEvent.ON_ITEM_LOAD_ERROR, null, event.text ) );
		}
		
		protected function onSecurityError( event:SecurityErrorEvent ):void
		{
			dispatchEvent( new QueueLoaderEvent( QueueLoaderEvent.ON_ITEM_LOAD_ERROR, null, event.text ) );
		}
		
	}
}